package orgx.wxyz.util;

import java.io.File;
import java.util.LinkedList;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>
 * 和文件相关的工具
 * </p>
 * 
 * @author hyhjwzx@126.com
 * @date 2013-4-16 上午11:06:58
 */
public final class FileUtil {
	/**
	 * 日子工具类
	 */
	private static final Logger logger = LoggerFactory.getLogger(FileUtil.class);
	
	/**
	 * 要删除的文件名的正则表达式
	 */
	static Pattern p = null;

	/**
	 * <p>
	 * 删除某个路径下的所有的指定文件或文件夹 <br><br>
	 * <i>不支持正则和任何模糊匹配</i>
	 * </p>
	 * 
	 * @param pathName
	 *            路径字符串
	 * @param delFileName
	 *            要删除的文件或文件夹名字
	 */
	public static void delFileOrDir(String pathName, String delFileName) {
		if (StringUtil.isBlank(pathName) || StringUtil.isBlank(delFileName)) {
			logger.error("参数错误，路径或文件名不能为空");
			throw new IllegalArgumentException("参数错误，路径或文件名不能为空");
		}

		// 验证路径是否存在
		File dir = new File(pathName);
		if (!dir.exists()) {
			logger.error("参数错误，路径名不存在: {}", pathName);
			throw new IllegalArgumentException("参数错误，路径名不存在:" + pathName);
		}
		logger.info("delete path : {}", pathName);
		
		// 编译要删除的文件的正则表达式对象
		p = Pattern.compile(delFileName);

		// 所有目录列表
		LinkedList<File> listDir = new LinkedList<File>();

		// 判断本路径是否就是要删除的目录或文件
		if (isDelDirOrFile(dir, delFileName)) {
			if (dir.isDirectory()) {
				delDir(dir);
			} else {
				logger.info("[Delete File] {}", dir.getAbsolutePath());
				dir.delete();
			}
		}
		listDir.add(dir);

		File tmp;
		File[] tmps;
		// 遍历当前目录下的所有下级目录和文件
		while (!listDir.isEmpty()) {
			tmp = listDir.removeFirst();

			// 遍历当前目录下的第一级子目录和文件
			tmps = tmp.listFiles();
			if (tmps == null) {
				continue;
			}

			// 删除指定目录或文件夹，否则将目录添加到目录列表中
			for (File file : tmps) {
				// 如果是要删除的文件或文件夹，则删除
				if (isDelDirOrFile(file, delFileName)) {
					if (file.isDirectory()) {
						delDir(file);
					} else {
						logger.info("[Delete File] {}", file.getAbsolutePath());
						file.delete();
					}
					continue;
				}

				if (file.isDirectory()) {
					listDir.add(file);
				}
			}
		}
	}
	
	/**
	 * <p>
	 * 验证目录或文件是否就是要删除的
	 * </p>
	 * @param file 要验证的目录或文件
	 * @param delFileName 要删除的目录或文件名
	 * @return 验证结果
	 */
	static boolean isDelDirOrFile(File file, String delFileName) {
		String fileName = file.getName();
		
		// 调用正则匹配
//		Matcher m = p.matcher(fileName);
//		return m.matches();
		
		return delFileName.equals(fileName);
	}

	/**
	 * <p>
	 * 删除目录，递归删除其中的目录和文件
	 * </p>
	 * @param dir
	 *            目录文件对象
	 */
	private static void delDir(File dir) {
		// 得到目录下的子目录或文件
		File[] files = dir.listFiles();

		// 清空子目录和文件
		for (File file : files) {
			if (file.isDirectory()) {
				delDir(file);
			} else {
				logger.info("[Delete File] {}", file.getAbsolutePath());
				file.delete();
			}
		}

		// 删除目录
		logger.info("[Delete Dir] {}", dir.getAbsolutePath());
		dir.delete();
	}
}
